import { type MouseEvent, useContext, useEffect, useState } from 'react';
import { PostIdH5PageContext } from '@/contexts/mobile/PostId';
import type {
  IPostComment,
  IPostCommentParentReply,
  IPostCommentReply,
  IQueryParams,
  IUserOv,
} from '@/interfaces';
import Link from 'next/link';
import Image from 'next/image';
import classNames from 'classnames';
import { getUserAvatar, toRelativeTime } from '@/lib/tool';
import useOffcanvas from 'hooks/useOffcanvas';
import ParentReplyPostIdH5Page from '@/app/[locale]/mobile/posts/[id]/parentReply';
import LoadMoreBtn from '@/app/[locale]/mobile/posts/[id]/loadMoreBtn';
import { useInfiniteQuery } from '@tanstack/react-query';
import { queryAllReplyByCommentId } from '@/services/api';
import useToast from 'hooks/useToast';
import ParentReplyBtnPostIdH5Page from '@/app/[locale]/mobile/posts/[id]/parentReplyBtn';

export default function ReplyPostIdH5Page({
  isClickLoadMore,
  itemData,
}: {
  isClickLoadMore?: boolean;
  itemData: IPostComment;
}) {
  const [queryParams, setQueryParams] = useState<IQueryParams>({});
  const [pages, setPages] = useState<IPostCommentReply[]>(itemData.content);
  const { show } = useToast();

  const replyQuery = useInfiniteQuery(
    ['/forum', '/replies', '/comments', itemData.comment.id, queryParams],
    async (context) => {
      return (await queryAllReplyByCommentId({
        id: context.queryKey[3],
        query: {
          ...(context.queryKey[4] as IQueryParams),
          ...context.pageParam,
        },
      })) as IPostComment;
    },
    {
      enabled: isClickLoadMore,
      keepPreviousData: true,
      getPreviousPageParam: (firstPage) => {
        if (firstPage.pageable.previous) {
          return {
            page: Math.max(firstPage.pageable.page - 1, 0),
            size: firstPage.pageable.size,
          };
        }
      },
      getNextPageParam: (lastPage) => {
        if (lastPage.pageable.next) {
          return {
            page: Math.min(lastPage.pageable.page, lastPage.pageable.pages),
            size: lastPage.pageable.size,
          };
        }
      },
      initialData: () => {
        return {
          pages: [itemData],
          pageParams: [
            {
              page: Math.max(itemData.pageable.page - 1, 0),
              size: itemData.pageable.size,
            },
          ],
        };
      },
    },
  );

  useEffect(() => {
    if (replyQuery.data) {
      setPages(
        replyQuery.data.pages
          .flatMap((item) => item.content)
          .map((item) => {
            item.reply._createdOnText = toRelativeTime(item.reply.createdOn);
            item.content.forEach((value) => {
              value.reply._createdOnText = toRelativeTime(
                value.reply.createdOn,
              );
            });
            return item;
          }),
      );
    }
  }, [replyQuery.data]);

  async function onClickLoadMore() {
    try {
      await replyQuery.fetchNextPage();
    } catch (e) {
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  return (
    <div className="vstack gap-4">
      {pages.map((item, index) => {
        return (
          <Item
            key={item.reply.id}
            index={index}
            id={item.reply.id}
            content={item.reply.content}
            user={item.user}
            createdOn={item.reply.createdOn}
            _createdOnText={item.reply._createdOnText}
            items={item.content}
            itemData={item}
          />
        );
      })}

      <LoadMoreBtn
        isDisabled={!replyQuery.hasNextPage || replyQuery.isFetchingNextPage}
        isLoading={replyQuery.isFetchingNextPage}
        onClickLoadMore={onClickLoadMore}
      />

      <div></div>
    </div>
  );
}

const Item = ({
  id,
  content,
  index,
  user,
  createdOn,
  _createdOnText,
  items,
  itemData,
}: {
  id: number;
  content: string;
  index: number;
  user: IUserOv;
  createdOn: string;
  _createdOnText: string | undefined;
  items: IPostCommentParentReply[];
  itemData: IPostCommentReply;
}) => {
  return (
    <div className="vstack gap-2">
      <Name
        id={id}
        createdOn={createdOn}
        _createdOnText={_createdOnText}
        user={user}
        left={index % 2 === 0}
      />
      <Content id={id} items={items} content={content} itemData={itemData} />
    </div>
  );
};

const Name = ({
  id,
  createdOn,
  _createdOnText,
  user,
  left = true,
  width = 56,
  height = 56,
  bgColor = 'bg-white',
  stickyTop = true,
}: {
  id: number;
  createdOn: string;
  _createdOnText: string | undefined;
  user: IUserOv;
  left?: boolean;
  width?: number;
  height?: number;
  bgColor?: string;
  stickyTop?: boolean;
}) => {
  const context = useContext(PostIdH5PageContext);
  const metadata = context.metadata!;
  const env = metadata.env;

  return (
    <div
      className={classNames(
        'hstack gap-4 py-2 pb-3',
        {
          'flex-row-reverse': !left,
          'sticky-top': stickyTop,
        },
        bgColor ? bgColor : false,
      )}
    >
      <div className="hstack gap-4 justify-content-between align-items-center flex-grow-1">
        <div className="hstack gap-4 align-items-center">
          <div className="flex-shrink-0">
            <Link
              href={`/users/${user.id}`}
              className="text-reset text-decoration-none text-decoration-underline-hover"
            >
              <Image
                className="rounded-4"
                src={getUserAvatar(user, metadata).mediumAvatarUrl}
                alt="avatar"
                width={width}
                height={height}
                placeholder="blur"
                blurDataURL={env.APP_BLUR_DATA_URL}
              />
            </Link>
          </div>
          <div
            className={classNames('flex-grow-1 vstack gap-2', {
              'text-end': !left,
            })}
          >
            <Link
              href={`/users/${user.id}`}
              className="text-reset text-decoration-none text-decoration-underline-hover"
            >
              {user.alias}
            </Link>
            <time dateTime={createdOn} className="text-secondary small">
              {_createdOnText}
            </time>
          </div>
        </div>
        <ParentReplyBtnPostIdH5Page id={id} alias={user.alias} />
      </div>
    </div>
  );
};

const Content = ({
  id,
  content,
  items,
  itemData,
}: {
  id: number;
  content: string;
  items: IPostCommentParentReply[];
  itemData: IPostCommentReply;
}) => {
  return (
    <div className="border rounded-4 bg-light-subtle vstack gap-3 p-3 overflow-hidden">
      <div className="vstack gap-3 justify-content-center">
        <div
          className="content-layer"
          dangerouslySetInnerHTML={{ __html: content }}
        />
        {items.length > 0 && (
          <div className="vstack gap-4">
            <PartialReplyContent id={id} items={items} />
            <ViewMoreReplies itemData={itemData} />
          </div>
        )}
      </div>
    </div>
  );
};

const PartialReplyContent = ({
  id,
  items,
}: {
  id: number;
  items: IPostCommentParentReply[];
}) => {
  return (
    <div className="vstack gap-2 border rounded-4 bg-light-subtle p-3">
      {items.map((item, index) => {
        return (
          <div key={item.reply.id}>
            <Name
              id={id}
              width={48}
              height={48}
              createdOn={item.reply.createdOn}
              _createdOnText={item.reply._createdOnText}
              user={item.user}
              left={index % 2 === 0}
              bgColor=""
              stickyTop={false}
            />
            <div
              className="content-layer"
              dangerouslySetInnerHTML={{ __html: item.reply.content }}
            />
          </div>
        );
      })}
    </div>
  );
};

const ViewMoreReplies = ({ itemData }: { itemData: IPostCommentReply }) => {
  const context = useContext(PostIdH5PageContext);
  const metadata = context.metadata!;
  const { isLoadingOffcanvasShowing, showOffcanvas } = useOffcanvas();
  const [isLoading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(isLoadingOffcanvasShowing);
  }, [isLoadingOffcanvasShowing]);

  function onClickSeeMore(e: MouseEvent<HTMLAnchorElement>) {
    e.stopPropagation();
    e.preventDefault();

    if (isLoading) {
      return;
    }

    showOffcanvas({
      title: `@${itemData.user.alias}`,
      bottom: true,
      content: (
        <PostIdH5PageContext.Provider value={{ metadata }}>
          <ParentReplyPostIdH5Page isClickLoadMore={true} itemData={itemData} />
        </PostIdH5PageContext.Provider>
      ),
      offcanvasBodyClass: 'pt-0',
      backdrop: false,
      offcanvasStyle: {
        height: '85vh',
      },
    });
  }

  return (
    <div className="small">
      <a
        onClick={onClickSeeMore}
        className="text-decoration-none text-decoration-underline-hover"
      >
        <span>查看更多回复</span>
        {isLoading ? (
          <span
            className="text-primary spinner-border spinner-border-sm ms-1"
            role="status"
            aria-hidden="true"
          ></span>
        ) : (
          <i className="bi bi-chevron-right ms-1"></i>
        )}
      </a>
    </div>
  );
};
